#pragma once

#if defined(__CUDACC__)

#if defined(__CUDACC_RTC__)

#define _CRTIMP
#define __THROW

#else /* !__CUDACC_RTC__ */
/* check host compiler version  */

/* check for host compilers that are compatible with nvcc */
#if !defined(__GNUC__) && !defined(_WIN32)

#error--- !!! UNSUPPORTED COMPILER !!! ---

#endif /* !__GNUC__ && !_WIN32 */

/* check invalid configurations */
#if defined(__PGIC__)
#if !defined(__GNUC__) || !defined(__LP64__) || !defined(__linux__)
#error-- unsupported pgc++ configuration! pgc++ is supported only on Linux x86_64!
#endif /* !defined(__GNUC__) || !defined(__LP64__) || !defined(__linux__) */
#endif /* defined(__PGIC__) */

#if defined(__powerpc__)
#if !defined(__powerpc64__) || !defined(__LITTLE_ENDIAN__)
#error-- unsupported PPC platform! Only 64-bit little endian PPC is supported!
#endif /* !__powerpc64__ || !__LITTLE_ENDIAN__ */
#endif /* __powerpc__ */

#if defined(__APPLE__) && defined(__MACH__) && !defined(__clang__)
#error-- clang and clang++ are the only supported host compilers on Mac OS X!
#endif /* __APPLE__ && __MACH__ && !__clang__ */

/* check host compiler version  */
#if !__NV_NO_HOST_COMPILER_CHECK

#if defined(__ICC)

#if (__ICC != 1500 && __ICC != 1600 && __ICC != 1700 && __ICC != 1800 && !(__ICC >= 1900 && __ICC <= 2021)) || !defined(__GNUC__) || !defined(__LP64__)

#error-- unsupported ICC configuration! Only ICC 15.0, ICC 16.0, ICC 17.0, ICC 18.0, ICC 19.x and 20.x on Linux x86_64 are supported! The nvcc flag '-allow-unsupported-compiler' can be used to override this version check; however, using an unsupported host compiler may cause compilation failure or incorrect run time execution. Use at your own risk.

#endif /* (__ICC != 1500 && __ICC != 1600 && __ICC != 1700 && __ICC != 1800 && __ICC != 1900) || !__GNUC__ || !__LP64__ */

#endif /* __ICC */

#if defined(__PGIC__)
#if ((__PGIC__ != 18) && (__PGIC__ != 19) && (__PGIC__ != 20) && (__PGIC__ != 21) && !(__PGIC__ == 99 && __PGIC_MINOR__ == 99))
#error-- unsupported pgc++ configuration! Only pgc++ 18, 19, 20 and 21 are supported! The nvcc flag '-allow-unsupported-compiler' can be used to override this version check; however, using an unsupported host compiler may cause compilation failure or incorrect run time execution. Use at your own risk.

#endif
#endif /* __PGIC__ */

#if defined(__powerpc__)

#if defined(__ibmxl_vrm__) && !(__ibmxl_vrm__ >= 0x0d010000 && __ibmxl_vrm__ < 0x0d020000) && \
    !(__ibmxl_vrm__ >= 0x10010000 && __ibmxl_vrm__ < 0x10020000)

#error-- unsupported xlC version! only xlC 13.1 and 16.1 are supported. The nvcc flag '-allow-unsupported-compiler' can be used to override this version check; however, using an unsupported host compiler may cause compilation failure or incorrect run time execution. Use at your own risk.

#endif /* __ibmxl_vrm__ && !(__ibmxl_vrm__ >= 0x0d010000 && __ibmxl_vrm__ < 0x0d020000) && \
                           !(__ibmxl_vrm__ >= 0x10010000 && __ibmxl_vrm__ < 0x10020000) */

#endif /* __powerpc__ */

#if defined(__GNUC__)

#if __GNUC__ > 11

#error-- unsupported GNU version! gcc versions later than 11 are not supported! The nvcc flag '-allow-unsupported-compiler' can be used to override this version check; however, using an unsupported host compiler may cause compilation failure or incorrect run time execution. Use at your own risk.

#endif /* __GNUC__ > 11 */

#if defined(__clang__) && !defined(__ibmxl_vrm__) && !defined(__ICC) && !defined(__HORIZON__) && !defined(__APPLE__)

#if (__clang_major__ >= 13) || (__clang_major__ < 3) || ((__clang_major__ == 3) && (__clang_minor__ < 3))
#error-- unsupported clang version! clang version must be less than 13 and greater than 3.2 . The nvcc flag '-allow-unsupported-compiler' can be used to override this version check; however, using an unsupported host compiler may cause compilation failure or incorrect run time execution. Use at your own risk.

#endif /* (__clang_major__ >=  13) || (__clang_major__ < 3) || ((__clang_major__ == 3) &&  (__clang_minor__ < 3)) */

#endif /* defined(__clang__) && !defined(__ibmxl_vrm__) && !defined(__ICC) && !defined(__HORIZON__) && !defined(__APPLE__) */

#endif /* __GNUC__ */

#if defined(_WIN32)

#if _MSC_VER < 1910 || _MSC_VER >= 1930

#error-- unsupported Microsoft Visual Studio version! Only the versions between 2017 and 2019 (inclusive) are supported! The nvcc flag '-allow-unsupported-compiler' can be used to override this version check; however, using an unsupported host compiler may cause compilation failure or incorrect run time execution. Use at your own risk.

#elif _MSC_VER >= 1910 && _MSC_VER < 1910

#pragma message("support for this version of Microsoft Visual Studio has been deprecated! Only the versions between 2017 and 2019 (inclusive) are supported!")

#endif /* (_MSC_VER < 1910 || _MSC_VER >= 1930) || (_MSC_VER >= 1910 && _MSC_VER < 1910) */

#endif /* _WIN32 */
#endif

#if defined(__GNUC__)

#define _CRTIMP
#define _ACRTIMP

#include <features.h> /* for __THROW */
#endif
#endif /* __CUDACC_RTC__ */

#if defined(__cplusplus) && defined(__CUDA_ARCH__) && defined(__CUDACC_RTC__)

#if __CUDACC_RTC__
typedef char *va_list;
#else /* !__CUDACC_RTC__ */
#include <cstdarg>
#endif /* __CUDACC_RTC__ */

#undef va_start
#undef va_end
#undef va_arg

#define va_start(ap, x) (__cu_va_start(&ap, x))
#define va_end(ap) (__cu_va_end(&ap))
#define va_arg(ap, t) (*((t *)__cu_va_arg(&ap, (t *)0)))

#endif
#endif /* __CUDACC__ */
